import mediapipe as mp
import cv2
import numpy as np


class Hands:

    def __init__(self):
        self.mp_hands = mp.solutions.hands.Hands()
        self.frame = None
        self.landmark = []
        pass

    def draw_style(self, frame):
        # 实例化Hands对象
        # mp_hands = mp.solutions.hands.Hands()
        mp_hands = self.mp_hands
        # 将frame的BGR图像转换为RGB图像
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        # Processes an RGB image and returns the hand landmarks
        # and handedness of each detected hand.
        result = mp_hands.process(frame_rgb)
        hand_landmarks_list = result.multi_hand_landmarks
        if hand_landmarks_list is None:
            return
        landmarks = hand_landmarks_list[0]
        hand_landmarks = landmarks.landmark
        self.landmark = hand_landmarks
        # 连接点
        conns = mp.solutions.hands_connections.HAND_CONNECTIONS
        # 关键点样式
        hands_style = mp.solutions.drawing_utils.DrawingSpec(color=(0, 0, 255), thickness=2)
        # 连线样式
        conns_style = mp.solutions.drawing_utils.DrawingSpec(color=(0, 0, 0), thickness=2)
        # 进行关键点样式的绘制
        mp.solutions.drawing_utils.draw_landmarks(
            image=frame,
            landmark_list=landmarks,
            connections=conns,
            landmark_drawing_spec=hands_style,
            connection_drawing_spec=conns_style,
        )
        frame_h, frame_w, _ = frame.shape
        for index, lm in enumerate(hand_landmarks):
            x = round(lm.x*frame_w)
            y = round(lm.y*frame_h)
            # print(index, x, y)
            cv2.putText(frame, str(index), (x, y), fontFace=cv2.FONT_ITALIC, fontScale=0.4, color=(0, 0, 0), thickness=1)

    def ges_ture_num(self):
        """
        手势数字识别 利用Y轴来判断是否弯曲
        :return:
        """
        top_point_num = [4, 8, 12, 16, 20]
        finger_status = np.zeros((5,), dtype=np.int8)
        for index, num in enumerate(top_point_num):
            if index == 0:
                top_p = self.index_convert_num(num)[0]
                mid_p = self.index_convert_num(num-2)[0]
                finger_status[index] = top_p < mid_p
            else:

                top_p = self.index_convert_num(num)[1]
                mid_p = self.index_convert_num(num-2)[1]
                # 未弯曲
                finger_status[index] = top_p < mid_p
                # 弯曲
            if top_p > mid_p:
                print(index, top_p, mid_p)
        cnt = np.sum(finger_status)
        cv2.putText(self.frame, str(cnt), (20, 100), fontFace=cv2.FONT_ITALIC, fontScale=2, color=(255, 0, 0), thickness=10)

        pass

    def index_convert_num(self, index):
        frame_h, frame_w, _ = self.frame.shape
        lm = self.landmark[index]
        x = round(lm.x * frame_w)
        y = round(lm.y * frame_h)
        return x, y

        pass

    def process(self, frame):
        self.frame = frame
        self.draw_style(self.frame)
        self.ges_ture_num()
        pass


if __name__ == '__main__':
    mp_hands = Hands()
    cap = cv2.VideoCapture(0)
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        # 进行关键点检测
        mp_hands.process(frame)
        cv2.imshow('hands', frame)
        key = cv2.waitKey(60)
        if key == ' ':
            break
    cap.release()
    cv2.destroyAllWindows()